﻿
using System;
using System.Collections.Generic;
using System.Linq;

using Styx;
using Styx.WoWInternals;
using System.Drawing;
using Styx.CommonBot;
using Styx.Common.Helpers;
using Styx.CommonBot.Routines;
using System.Windows.Media;
using System.Text;

#region [Method] - Class Redundancy
using L = SinisterD.Core.Utilities.Log;
using Styx.Common;

internal static class DoBetween
{

      internal static bool Between(this double distance, double min, double max)
        {
            return distance >= min && distance <= max;
        }


        internal static bool Between(this float distance, float min, float max)
        {
            return distance >= min && distance <= max;
        }


        internal static bool Between(this int value, int min, int max)
        {
            return value >= min && value <= max;
        }
}
#endregion

namespace SinisterD.Core.Managers
{
    internal static class Talent_Manager
    {
        //public const int TALENT_FLAG_ISEXTRASPEC = 0x10000;
        public static bool HaveTalent(RogueTalents index) { return Talent_Manager.IsSelected((int)index); }   

        static Talent_Manager()
        {
        }

        public static void Init()
        {
            Talents = new List<Talent>();
            TalentId = new int[6];

            Lua.Events.AttachEvent("ACTIVE_TALENT_GROUP_CHANGED", UpdateTalentManager);
            Lua.Events.AttachEvent("LEARNED_SPELL_IN_TAB", UpdateTalentManager);
            Update();
            
        }

        public static List<Talent> Talents { get; private set; }

        private static int[] TalentId { get; set; }

        private static WaitTimer EventRebuildTimer = new WaitTimer(TimeSpan.FromSeconds(2));
        private static bool _reBuild = false;

        private static bool RebuildNeeded
        {
            get
            {
                return _reBuild;
            }
            set
            {
                _reBuild = value;
                EventRebuildTimer.Reset();
            }
        }

        public static bool IsSelected(int index)
        {
            // return Talents.FirstOrDefault(t => t.Index == index).Selected;
            int tier = (index - 1) / 3;
            if (tier.Between(0, 6))
                return TalentId[tier] == index;
            return false;
        }


        /// <summary>
        /// event handler for messages which should cause behaviors to be rebuilt
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private static void UpdateTalentManager(object sender, LuaEventArgs args)
        {
            
            int[] oldTalent = TalentId;

            L.diagnosticLog("{0} Event Fired!", args.EventName);

            Update();

            int i;
            for (i = 0; i < 6; i++)
            {
                if (oldTalent[i] != TalentId[i])
                {
                    RebuildNeeded = true;
                    L.diagnosticLog("TalentManager: Your talents have changed.");
                    break;
                }
            }
            L.diagnosticLog("TalentManager: RebuildNeeded={0}", RebuildNeeded);
        }

        /// <summary>
        /// loads WOW Talent info into cached list
        /// </summary>
        public static void Update()
        {
            // Keep the frame stuck so we can do a bunch of injecting at once.
            using (StyxWoW.Memory.AcquireFrame())
            {
              
                Talents.Clear();
                TalentId = new int[7];

                // Always 21 talents. 7 rows of 3 talents.
                for (int row = 0; row < 7; row++)
                {
                    for (int col = 0; col < 3; col++)
                    {
                        var selected = Lua.GetReturnVal<bool>(string.Format("local t = select(4, GetTalentInfo({0}, {1}, GetActiveSpecGroup())) if t then return 1 end return nil", row + 1, col + 1), 0);
                        int index = 1 + row * 3 + col;
                        var t = new Talent { Index = index, Selected = selected };
                        Talents.Add(t);
                        Logging.Write(Colors.OrangeRed, "TalentManager: Talents Updated");

                        if (selected)
                            TalentId[row] = index;
                    }
                }

            }

        }

        public static bool Pulse()
        {
            if (RebuildNeeded && EventRebuildTimer.IsFinished)
            {
                RebuildNeeded = false;
                L.diagnosticLog("TalentManager: Rebuilding behaviors due to changes detected.");
                Logging.Write(Colors.LimeGreen, "TM-Pulse now");
                Update();   // reload talents just in case
                return true;
            }

            return false;
        }


        #region Nested type: Talent

        public struct Talent
        {
            public bool Selected;
            public int Index;
        }

        #endregion
        public enum RogueTalents
        {

            Nightstalker = 1,
            Subterfuge,
            ShadowFocus,

            DeadlyThrow,
            NerveStrike,
            CombatReadiness,
          
            CheatDeath,
            LeechingPoison,
            Elusiveness,

            CloakAndDagger,
            Shadowstep,
            BurstOfSpeed,

            PreyonTheWeak,
            InternalBleeding,
            DirtyTricks,

            ShurikenToss,
            MarkedForDeath,            
            Anticipation,

            VenomRush,
            ShadowReflection,           
            DeathFromAbove
        }

    }
}